package cn.ujn.medicalbackend.service.impl;

import cn.ujn.medicalbackend.common.ErrorCode;
import cn.ujn.medicalbackend.domain.Account;
import cn.ujn.medicalbackend.exception.BusinessException;
import cn.ujn.medicalbackend.mapper.AccountMapper;
import cn.ujn.medicalbackend.mapper.RolePermissionMapper;
import cn.ujn.medicalbackend.service.AccountService;
import cn.ujn.medicalbackend.service.RolePermissionService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static cn.ujn.medicalbackend.constant.AccountConstant.ACCOUNT_LOGIN_STATE;
import static cn.ujn.medicalbackend.constant.AccountConstant.ADMIN_ROLE;

/**
 * @author 26532
 * @description 针对表【account】的数据库操作Service实现
 * @createDate 2024-10-24 12:12:34
 */
@Service
@Slf4j
public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account>
        implements AccountService {

    @Autowired
    private AccountMapper accountMapper;

    @Autowired
    private RolePermissionService rolePermissionService;

    /**
     * 盐值，混淆密码
     */
    private static final String SALT = "xincheng";


    @Override
    public Account accountLogin(String uname, String pwd, HttpServletRequest request) {
        // 1. 校验
        if (StringUtils.isAllBlank(uname, pwd)) {
            throw new BusinessException(ErrorCode.NULL_ERROR);
        }
        if (uname.length() < 4) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号长度过长");
        }
        if (pwd.length() < 8) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "密码长度过短");
        }

        // 账户不能有特殊字符
        String validPattern = "[`~!@#$%^&*()+=|{}':;',\\\\[\\\\].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？]";
        Matcher matcher = Pattern.compile(validPattern).matcher(uname);
        if (matcher.find()) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号不能有特殊字符");
        }
        // 2. 加密
        String encryptPassword = DigestUtils.md5DigestAsHex((SALT + pwd).getBytes());
//        System.out.println("pwd:" + encryptPassword);
        //查询用户是否存在‘
        QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("uname", uname);
        queryWrapper.eq("pwd", encryptPassword);
        Account account = accountMapper.selectOne(queryWrapper);
        //用户不存在
        if (account == null) {
            log.info("account login failed, uname cannot match pwd");
            throw new BusinessException(ErrorCode.NOT_LOGIN, "账号密码错误");
        }
        // 3.用户脱敏
        Account safetyAccount = getSafetyAccount(account);
        // 4.记录用户登录态

        request.getSession().setAttribute(ACCOUNT_LOGIN_STATE, safetyAccount);

        return safetyAccount;
    }

    @Override
    public int userLogout(HttpServletRequest request) {
        //移除登录态
        request.getSession().removeAttribute(ACCOUNT_LOGIN_STATE);
        return 1;
    }

    /**
     * 用户信息脱敏
     *
     * @param originAccount
     * @return
     */
    public Account getSafetyAccount(Account originAccount) {
        if (originAccount == null) {
            throw new BusinessException(ErrorCode.NULL_ERROR);
        }
        Account safetyAccount = new Account();
        safetyAccount.setId(originAccount.getId());
        safetyAccount.setUname(originAccount.getUname());
        safetyAccount.setRealname(originAccount.getRealname());
        safetyAccount.setPhonenumber(originAccount.getPhonenumber());
        safetyAccount.setUtype(originAccount.getUtype());
        safetyAccount.setCreatetime(originAccount.getCreatetime());
        safetyAccount.setUpdatetime(originAccount.getUpdatetime());
        return safetyAccount;
    }

    @Override
    public Account getLoginAccount(HttpServletRequest request) {
        if (request == null) {
            return null;
        }
        Object accountObj = request.getSession().getAttribute(ACCOUNT_LOGIN_STATE);
        if (accountObj == null) {
            throw new BusinessException(ErrorCode.NOT_LOGIN);
        }
        return (Account) accountObj;
    }

    @Override
    public boolean isAdmin(HttpServletRequest request) {
        if (request == null) {
            return false;
        }
        Object accountObj = request.getSession().getAttribute(ACCOUNT_LOGIN_STATE);
        Account account = (Account) accountObj;
        return account != null && ADMIN_ROLE.equals(account.getUtype());
    }
}




